home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
graphics
/
mktil16a.zip
/
HEADERS.ZIP
/
FONT.H
next >
Wrap
C/C++ Source or Header
|
1994-09-15
|
9KB
|
416 lines
/* make sure stdlib.h is in */
#ifndef _FAR_
#include <stdlib.h>
#endif
#ifndef NORMAL
#define INVERSE 0
#define NORMAL 1
#define MASK 2
#define ERASE 3
#define ERASE_INVERSE 4
#endif
#ifndef byte
#define byte unsigned char
#define word unsigned int
#define d_word unsigned long
#endif
/* in case graphics.h is not going... */
#ifndef SCREEN
#define SCREEN (byte huge *)0xA0000000
byte huge *screen;
#endif
#define FONT_CHARACTERS 256
#define FONT_CHARACTER_SIZE 8
#define FONT_X 8
#define FONT_Y 8
byte huge **font;
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
void put_font(int x, int y, byte ascii, byte color, byte option)
{
/* set up tileseg and tileoff with the segment and offset of the font */
/* scrnseg and scrnoff contain the segment and offset of the screen buffer
which, if I assigned it to Video Mem, would be 0xA000 and 0x0000
respectively */
word tileseg=FP_SEG(font[ascii]),
tileoff=FP_OFF(font[ascii]),
scrnseg=FP_SEG(screen),
scrnoff=FP_OFF(screen)+(y<<8)+(y<<6)+x;
/* normal just draws the character's on pixesl. black is transparent. */
if (option==NORMAL)
{
_asm
{
/* save the data segment */
push ds
/* load ds:si register pair with segment and offset of font */
mov ax,[tileseg]
mov ds,ax
mov si,[tileoff]
/* likewise, load es:di register pair with segment:offset of where to
put it */
mov ax,[scrnseg]
mov es,ax
mov di,[scrnoff]
/* Alow contains the color to draw the font with, and cx is our loop var. */
mov al,[color]
mov cx,FONT_Y
start:
push cx
/* get a byte of the font. this is 8 pixels. */
mov bl,[si]
mov cx,FONT_X
/* now we loop through the byte using a shift and draw each pixel. */
mid:
/* copy the byte so we can keep the original. */
mov bh,bl
/* keep the 1st bit which is the pixel we wish to draw */
and bh,0x01
/* if the bit is 1, it is on, and so we draw it. */
dec bh
jz draw
/* otherwise, skip and continue... */
jmp mid_end
draw:
/* move the 'color' (which was in Alow) to the screen (buffer or wherever) */
mov es:[di],al
mid_end:
/* shift the byte to the right. it's like a conveyor belt...after we process
each bit, we throw off the right-most one (or left-most; it depends how you
look at it: I see it from right to left here...00000001 is 1, 00000010
is 2, etc.) and take the next-leftmost bit. 10101010 would become 01010101
*/
shr bl,1
/* move over one pixel on the screen (where we're drawing) */
inc di
/* finish processing the remaining bits in the byte we fetched */
loop mid
/* ok, now we get the next byte */
inc si
/* and, to draw the next 8 pixels 'under' the 1st 8, we go DOWN 1 vertical
screen row (+320 bytes) and subtract 8 horizontal pixels (-8 bytes). */
add di,320-FONT_X
pop cx
/* finished */
loop start
end:
/* restore data segment */
pop ds
}
}
else if (option==INVERSE)
{
/* this is basically the same as above... */
_asm
{
push ds
mov ax,[tileseg]
mov ds,ax
mov si,[tileoff]
mov ax,[scrnseg]
mov es,ax
mov di,[scrnoff]
mov al,[color]
mov cx,FONT_Y
start2:
push cx
mov bl,[si]
mov cx,FONT_X
mid2:
mov bh,bl
and bh,0x01
/* but instead of drawing on 1, we draw on 0. 1's are transparent. */
dec bh
jnz draw2
jmp mid_end2
draw2:
mov es:[di],al
mid_end2:
shr bl,1
inc di
loop mid2
inc si
add di,320-FONT_X
pop cx
loop start2
end2:
pop ds
}
}
else if (option==ERASE)
{
/* this is slightly different. we draw 1's, but ERASE 0's. */
_asm
{
push ds
mov ax,[tileseg]
mov ds,ax
mov si,[tileoff]
mov ax,[scrnseg]
mov es,ax
mov di,[scrnoff]
mov al,[color]
mov cx,FONT_Y
start3:
push cx
mov bl,[si]
mov cx,FONT_X
mid3:
mov bh,bl
and bh,0x01
dec bh
jz draw3
/* go ahead and draw 1's, but... */
/* erase any 'off' pixels by a 0 to screen memory. */
mov es:[di],0
jmp mid_end3
draw3:
mov es:[di],al
mid_end3:
shr bl,1
inc di
loop mid3
inc si
add di,320-FONT_X
pop cx
loop start3
end3:
pop ds
}
}
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/* this just uses put_font() to display a string of charactes. */
void put_string(int x, int y, char *string, byte color, byte option)
{
word a=0;
while (string[a]!='\0')
{
put_font(x,y,string[a],color,option);
x+=8;
a++;
}
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/* same here. just display a string of numbers. */
void put_number_i(int x, int y, int number, byte color, byte option)
{
word a=0;
byte buf[17];
itoa(number,buf,10);
put_string(x,y,buf,color,option);
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
void put_number_l(int x, int y, long number, byte color, byte option)
{
word a=0;
byte buf[17];
ltoa(number,buf,10);
put_string(x,y,buf,color,option);
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/* reads a 256 character 8x8 font stored as 8 bytes per character */
byte read_font(char *filename)
{
char buf[80];
size_t itemsread;
FILE *file;
int a;
sprintf(buf,"%s%s.fnt",path,filename);
if ((file=fopen(buf,"rb"))==NULL)
{
printf("Unable to open %s for read.\n",buf);
return (FAILURE);
}
for (a=0;a<FONT_CHARACTERS;a++)
{
itemsread=fread(font[a],1,FONT_CHARACTER_SIZE,file);
}
fclose(file);
return(SUCCESS);
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/* writes one. */
byte write_font(char *filename)
{
char buf[80];
size_t items_written;
FILE *file;
int a;
sprintf(buf,"%s%s.fnt",path,filename);
if ((file=fopen(buf,"rb"))==NULL)
{
printf("Unable to open %s for write.\n",buf);
return (FAILURE);
}
for (a=0;a<FONT_CHARACTERS;a++)
{
items_written=fread(font[a],1,FONT_CHARACTER_SIZE,file);
}
fclose(file);
return(SUCCESS);
}
/* that's it for this file. hope it helps! */
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
byte allocate_font(void)
{
int a;
font=(byte huge **)halloc((long)(FONT_CHARACTERS),4);
if (font==NULL)
{
printf("error allocating font pointers\n");
return(FAILURE);
}
for (a=0;a<FONT_CHARACTERS;a++)
{
font[a]=(byte huge *)halloc((long)(FONT_CHARACTER_SIZE),1);
if (font[a]==NULL)
{
printf("error allocating font %d\n",a);
return(FAILURE);
}
}
return(SUCCESS);
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
void free_font(void)
{
int a;
for (a=0;a<FONT_CHARACTERS;a++)
if (font[a]!=NULL) hfree(font[a]);
if (font!=NULL) hfree(font);
}